1 /* 2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021 3 License: [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License]. 4 Authors: Marcelo S. N. Mancini 5 6 Copyright Marcelo S. N. Mancini 2018 - 2021. 7 Distributed under the CC BY-4.0 License. 8 (See accompanying file LICENSE.txt or copy at 9 https://creativecommons.org/licenses/by/4.0/ 10 */ 11 12 module hip.graphics.material; 13 import hip.math.matrix; 14 import hip.math.vector; 15 import hip.error.handler; 16 import hip.hiprenderer.shader; 17 import hip.hiprenderer.shader.shadervar; 18 19 class Material 20 { 21 ShaderVar[string] variables; 22 Shader shader; 23 this(Shader s) 24 { 25 this.shader = s; 26 } 27 28 void setVertexVar(T)(string varName, T data){setVar(ShaderTypes.VERTEX, varName, data);} 29 void setFragmentVar(T)(string varName, T data){setVar(ShaderTypes.FRAGMENT, varName, data);} 30 alias setPixelVar = setFragmentVar; 31 void setGeometryVar(T)(string varName, T data){setVar(ShaderTypes.GEOMETRY, varName, data);} 32 33 34 35 36 void setVar(ShaderTypes t, string varName, bool data){setVar(t, varName, &data, UniformType.boolean, data.sizeof);} 37 void setVar(ShaderTypes t, string varName, int data){setVar(t, varName, &data, UniformType.integer, data.sizeof);} 38 void setVar(ShaderTypes t, string varName, uint data){setVar(t, varName, &data, UniformType.uinteger, data.sizeof);} 39 void setVar(ShaderTypes t, string varName, float data){setVar(t, varName, &data, UniformType.floating, data.sizeof);} 40 void setVar(ShaderTypes t, string varName, float[2] data){setVar(t, varName, &data, UniformType.floating2, data.sizeof);} 41 void setVar(ShaderTypes t, string varName, float[3] data){setVar(t, varName, &data, UniformType.floating3, data.sizeof);} 42 void setVar(ShaderTypes t, string varName, float[4] data){setVar(t, varName, &data, UniformType.floating4, data.sizeof);} 43 void setVar(ShaderTypes t, string varName, float[9] data){setVar(t, varName, &data, UniformType.floating3x3, data.sizeof);} 44 void setVar(ShaderTypes t, string varName, float[16] data){setVar(t, varName, &data, UniformType.floating4x4, data.sizeof);} 45 void setVar(ShaderTypes t, string varName, Vector2 data){setVar(t, varName, &data, UniformType.floating2, data.sizeof);} 46 void setVar(ShaderTypes t, string varName, Vector3 data){setVar(t, varName, &data, UniformType.floating3, data.sizeof);} 47 void setVar(ShaderTypes t, string varName, Vector4 data){setVar(t, varName, &data, UniformType.floating4, data.sizeof);} 48 void setVar(ShaderTypes t, string varName, Matrix3 data){setVar(t, varName, &data, UniformType.floating3x3, data.sizeof);} 49 void setVar(ShaderTypes t, string varName, Matrix4 data){setVar(t, varName, &data, UniformType.floating4x4, data.sizeof);} 50 51 protected void setVar(ShaderTypes t, string varName, void* varData, UniformType type, size_t varSize) 52 { 53 import core.stdc.string : memcpy; 54 ShaderVar* variable = (varName in variables); 55 if(variable is null) 56 { 57 ShaderVar s; 58 s.data = new void[varSize]; 59 s.name = varName; 60 s.shaderType = t; 61 s.type = type; 62 variables[varName] = s; 63 variable = (varName in variables); 64 } 65 memcpy(variable.data.ptr, varData, variable.varSize); 66 } 67 68 protected void setShaderVar(ref ShaderVar v) 69 { 70 switch(v.shaderType) with(ShaderTypes) 71 { 72 case FRAGMENT: 73 mixin(getSetShaderVarCall("Fragment")); 74 break; 75 case VERTEX: 76 mixin(getSetShaderVarCall("Vertex")); 77 break; 78 case GEOMETRY: 79 default: 80 break; 81 } 82 } 83 84 void bind() 85 { 86 shader.bind(); 87 foreach(ref ShaderVar v; variables) 88 setShaderVar(v); 89 } 90 } 91 92 private string getSetShaderVarCall(string shaderT) 93 { 94 import hip.util.string : replaceAll; 95 return q{ 96 final switch(v.type) with(UniformType) 97 { 98 case boolean: 99 shader.set$Var(v.name, *cast(bool*)v.data); 100 break; 101 case integer: 102 shader.set$Var(v.name, *cast(int*)v.data); 103 break; 104 case integer_array: 105 shader.set$Var(v.name, *cast(int[]*)v.data); 106 break; 107 case uinteger: 108 shader.set$Var(v.name, *cast(uint*)v.data); 109 break; 110 case uinteger_array: 111 shader.set$Var(v.name, *cast(uint[]*)v.data); 112 break; 113 case floating: 114 shader.set$Var(v.name, *cast(float*)v.data); 115 break; 116 case floating2: 117 shader.set$Var(v.name, *cast(float[2]*)v.data); 118 break; 119 case floating3: 120 shader.set$Var(v.name, *cast(float[3]*)v.data); 121 break; 122 case floating4: 123 shader.set$Var(v.name, *cast(float[4]*)v.data); 124 break; 125 case floating2x2: 126 break; 127 case floating3x3: 128 shader.set$Var(v.name, *cast(Matrix3*)v.data); 129 break; 130 case floating4x4: 131 shader.set$Var(v.name, *cast(Matrix4*)v.data); 132 break; 133 case floating_array: 134 shader.set$Var(v.name, *cast(float[]*)v.data); 135 break; 136 case texture_array: 137 break; 138 case none: 139 ErrorHandler.assertExit(false, "Can't set ShaderVar of type 'none'"); 140 }}.replaceAll('$', shaderT); 141 }